'''
Author: mypx
Date: 2025-10-21 15:29:21
LastEditTime: 2025-10-21 15:33:34
LastEditors: mypx mypx_coder@163.com
Description: 
'''
# 范围限制模块
from typing import Dict, Optional, Any
from PyQt6.QtWidgets import QWidget, QSpinBox, QLineEdit, QMessageBox
from PyQt6.QtCore import pyqtSignal, QObject
from parser.config_model import ConfigItem, RangeRestriction
from parser.expression_evaluator import ExpressionEvaluator

class RangeModule(QObject):
    """范围限制模块"""

    valueOutOfRange = pyqtSignal(str, int, int)  # config_id, min, max

    def __init__(self):
        super().__init__()
        self.expression_evaluator = ExpressionEvaluator()
        self.range_restrictions: Dict[str, RangeRestriction] = {}
    
    def register_range_restriction(self, config_item: ConfigItem) -> None:
        """注册配置项的范围限制"""
        if config_item.properties.range:
            self.range_restrictions[config_item.id] = config_item.properties.range
    
    def apply_range_restriction(self, config_item: ConfigItem, control: QWidget) -> None:
        """为配置控件应用范围限制"""
        restriction = self.range_restrictions.get(config_item.id)
        if not restriction:
            return
        
        # 只对数值类型应用范围限制
        if config_item.properties.type in ['int', 'hex']:
            if isinstance(control, QSpinBox):
                control.setRange(restriction.min, restriction.max)
            elif isinstance(control, QLineEdit) and config_item.properties.type == 'hex':
                # 为十六进制输入框添加验证
                def validate_hex(input_str: str) -> bool:
                    try:
                        if not input_str:
                            return True
                        value = int(input_str.replace('0x', ''), 16)
                        return restriction.min <= value <= restriction.max
                    except ValueError:
                        return False
                
                # 这里可以添加自定义验证器
                pass
    
    def validate_value(self, config_id: str, value: int, config_values: Dict[str, any]) -> bool:
        """验证值是否在范围内"""
        restriction = self.range_restrictions.get(config_id)
        if not restriction:
            return True
        
        # 检查条件是否满足
        if restriction.condition and not self.expression_evaluator.evaluate(
            restriction.condition.expression, config_values
        ):
            return True
        
        if not (restriction.min <= value <= restriction.max):
            self.valueOutOfRange.emit(config_id, restriction.min, restriction.max)
            return False
        
        return True
    
    def show_range_error(self, config_name: str, min_val: int, max_val: int) -> None:
        """显示范围错误提示"""
        QMessageBox.warning(
            None,
            "Value Out of Range",
            f"The value for {config_name} must be between {min_val} and {max_val}."
        )